from onecup.settings import MONITOR_URL
from myscheduler.models import PromResult
import time
import requests

class promQL:

    def executePromQL(self, expr):
        response = requests.request('GET', expr)
        if response.status_code == 200:
            if len(response.json()['data']['result']) != 0:
                value = response.json()['data']['result']
        else:
            value = []

        return value


    def tanstodict(self, inlist):
        outdict = {}
        for item in inlist:
            ipaddr = self.getip(item['metric']['instance'].rpartition(':')[0])
            outdict[ipaddr] = round(float(item['value'][1]), 2)
        return outdict

    def TansOS(self, inlist):
        outdict = {}
        for item in inlist:
            #ip = item.get('metric').get('instance')
            #ip = ip[:ip.index(':')] if ':' in ip else ip
            ip = item.get('metric').get('instance').rpartition(':')[0]
            if ip:
                tmp = ip.strip('[')
                ip = tmp.strip(']')
            os_name = item.get('metric').get('pretty_name')
            os_name = os_name[:os_name.index(':')] if ':' in os_name else os_name
            outdict[ip] = os_name
        return outdict

    def TansHost(self, inlist):
        outdict = {}
        for item in inlist:
            #ip = item.get('metric').get('instance')
            #ip = ip[:ip.index(':')] if ':' in ip else ip
            ip = item.get('metric').get('instance').rpartition(':')[0]
            if ip:
                tmp = ip.strip('[')
                ip = tmp.strip(']')
            os_name = item.get('metric').get('nodename')
            os_name = os_name[:os_name.index(':')] if ':' in os_name else os_name
            outdict[ip] = os_name
        return outdict

    def TansType(self, inlist):
        outdict = {}
        for item in inlist:
            #ip = item.get('metric').get('instance')
            #ip = ip[:ip.index(':')] if ':' in ip else ip
            ip = item.get('metric').get('instance').rpartition(':')[0]
            if ip:
                tmp = ip.strip('[')
                ip = tmp.strip(']')
            os_name = item.get('metric').get('product_name')
            os_name = os_name[:os_name.index(':')] if ':' in os_name else os_name
            outdict[ip] = os_name
        return outdict

    def getip(self, instance):
        ipinfo = instance
        if instance:
            tmp = instance.strip('[')
            ipinfo = tmp.strip(']')
        return ipinfo


    def getnodeinfo(self, interval):
        preexpr = MONITOR_URL + 'api/v1/query?query='
        NODEPORT = ('9100', '9101')
        upexpr = 'up==1'
        cpunumexpr = 'count(node_cpu_seconds_total{mode="system"}) by (instance)'
        memnumexpr = 'round(node_memory_MemTotal_bytes/1024^3)'
        cpuavgexpr = '(1-(avg(irate(node_cpu_seconds_total{mode="idle"}['+interval+'])) by (instance))) * 100'
        cpumaxexpr = '(1-(min(irate(node_cpu_seconds_total{mode="idle"}['+interval+'])) by (instance))) * 100'
        #memusageexpr = '(1 - (node_memory_MemAvailable_bytes / (node_memory_MemTotal_bytes))) * 100'
        memusageexpr = '(1 - ( node_memory_MemFree_bytes %2B node_memory_Buffers_bytes %2B node_memory_Cached_bytes - node_memory_Shmem_bytes - node_memory_SUnreclaim_bytes) / (node_memory_MemTotal_bytes )) * 100'
        diskusageexpr = '(1-sum(node_filesystem_free_bytes{device=~"/dev/sd[a-z].?"})by(instance)/sum(node_filesystem_size_bytes{device=~"/dev/sd[a-z].?"}) by(instance))*100'
        ioreadexpr = 'max(irate(node_disk_reads_completed_total{device=~"sd.*|dm.*"}['+interval+'])) by (instance)'
        iowriteexpr = 'max(irate(node_disk_writes_completed_total{device=~"sd.*|dm.*"}['+interval+'])) by (instance)'
        osexpr = 'node_os_info'
        hostexpr = 'node_uname_info'
        dmiexpr = 'node_dmi_info'
        uplist = self.executePromQL(preexpr+upexpr)
        cpunum = self.executePromQL(preexpr+cpunumexpr)
        memnum = self.executePromQL(preexpr+memnumexpr)
        cpuavg = self.executePromQL(preexpr+cpuavgexpr)
        cpumax = self.executePromQL(preexpr+cpumaxexpr)
        memusage = self.executePromQL(preexpr+memusageexpr)
        diskusage = self.executePromQL(preexpr+diskusageexpr)
        ioread = self.executePromQL(preexpr+ioreadexpr)
        iowrite = self.executePromQL(preexpr+iowriteexpr)
        osname = self.executePromQL(preexpr+osexpr)
        hostname = self.executePromQL(preexpr+hostexpr)
        hosttype = self.executePromQL(preexpr+dmiexpr)
        cpunumdict = self.tanstodict(cpunum)
        memnumdict = self.tanstodict(memnum)
        cpuavgdict = self.tanstodict(cpuavg)
        cpumaxdict = self.tanstodict(cpumax)
        memusagedict = self.tanstodict(memusage)
        diskusagedict = self.tanstodict(diskusage)
        ioreaddict = self.tanstodict(ioread)
        iowritedict = self.tanstodict(iowrite)
        osnamedict = self.TansOS(osname)
        hostnamedict = self.TansHost(hostname)
        hosttypedict = self.TansType(hosttype)
        fetchdate = time.strftime("%Y%m%d%H", time.localtime())
        for item in uplist:
            instanceinfo = item['metric']['instance'].rpartition(':')
            if len(instanceinfo) == 3:
                if instanceinfo[2] in NODEPORT:
                    i = self.getip(instanceinfo[0])
                    PromResult.objects.update_or_create(
                        defaults={'cpunum': cpunumdict.get( i, -1),'memnum': memnumdict.get( i, -1),'cpuavg': cpuavgdict.get( i, -1), 'cpumax': cpumaxdict.get( i, -1), 'memusage':memusagedict.get( i, -1), 'diskusage': diskusagedict.get( i, -1),'ioread': ioreaddict.get( i, -1),'iowrite': iowritedict.get( i, -1),'hostname':hostnamedict.get( i, -1),'osname':osnamedict.get( i, -1),'hosttype':hosttypedict.get( i, -1)},
                        ip=i,
                        interval=interval,
                        fetchdate=fetchdate
                    )
